from sklearn.datasets import load_iris # 鸢尾花数据示例
from sklearn.neighbors import KNeighborsClassifier
# 导入数据集拆分工具
from sklearn.model_selection import train_test_split
# 可视化库
import matplotlib.pyplot as plt
import seaborn as sns

iris = load_iris()
print('keys:', iris.keys())
print('feature_names:', iris.feature_names)
print('target:', iris.target)

print('===============2.拆分数据集===================')
# 2. 拆分数据集

# 将样本的特征和标签分别复制给x和y

x, y = iris.data, iris.target
print(x.shape)  # 拆分前 (150, 4) 样本数据量工150个，每个样本有4个特征

# 将x，y拆分为训练集和验证集
x_train, x_test, y_train, y_test = train_test_split(x, y)
print('x_train:', x_train.shape)  # 拆分后训练集合 （112， 4）
print('x_test:', x_test.shape)  # 拆分后验证集合 （38， 4）
print('y_train:', y_train.shape)  # 拆分后训练集合 （112，）
print('y_test:', y_test.shape)  # 拆分后验证集合 （38，）

# 3. 训练模型并评估准确率

# 创建KNN分类器，参数保持默认设置---分类
knn_clf = KNeighborsClassifier()
# 使用训练集拟合模型
knn_clf.fit(x_train, y_train)

# 查看模型在训练集和验证集中的准确率
print('knn_clf:训练集准确率：%.3f' % knn_clf.score(x_train, y_train))
print('knn_clf:验证集准确率：%.3f' % knn_clf.score(x_test, y_test))

# 导入网络搜索
from sklearn.model_selection import GridSearchCV

# 定义一个从1-10的n_neighbors
n_neighbors = tuple(range(1, 11, 1))  # [1-11)每个一个数取值，存储元祖，(1,2,3,...10)
# 创建网络搜索实例，estimator用KNN分类器
# 把刚刚定义的n_neighbors传入给param_grid参数
# cv参数指交叉验证次数为5
cv = GridSearchCV(estimator=KNeighborsClassifier(),
                  param_grid={'n_neighbors': n_neighbors},
                  cv=5)
# 使用网络搜索拟合数据集
cv.fit(x, y)

# 查看最优参数
print('最优参数：', cv.best_params_)  # {'n_neighbors': 6}
print('最优得分：', cv.best_score_)  # {'n_neighbors': 6}


# 使用最优参数查看训练集和验证集的准确率

# 创建KNN分类器，参数保持默认设置
knn_clf_best = KNeighborsClassifier(n_neighbors=6)
# 使用训练集拟合模型
knn_clf_best.fit(x_train, y_train)

# 查看模型在训练集和验证集中的准确率
print('knn_clf_best:训练集准确率：%.3f' % knn_clf_best.score(x_train, y_train))
print('knn_clf_best:验证集准确率：%.3f' % knn_clf_best.score(x_test, y_test))
